/*
 *  Copyright 2012 Ricardo Engel
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.mookt.unit;

import java.io.Serializable;

/**
 * A unit of measurement (or simply unit) is a definite magnitude of quantity,
 * defined and adopted by convention and/or by law. Any other value of the
 * quantity can be expressed as a simple multiple of the unit of measurement.
 * 
 * Units are defined by their symbol and, optionally, a dimension. Dimensionless
 * units is a unit without an associated dimension. Dimensionless units are
 * widely used in mathematics, physics, engineering, economics, and in everyday
 * life (such as in counting). Examples of non-dimensionless physical units are
 * metre, second and kilogram, whereas radian and steradian are dimensionless
 * units.
 * 
 * <p>
 * Although this is not enforced, it is recommended that classes implementing
 * this interface are made immutable.
 * </p>
 * 
 * @author Ricardo Engel
 */
public interface Unit extends Serializable {

    /**
     * Returns the internationally accepted symbol representing this unit.
     * 
     * <p>
     * In general, this method should return a string that
     * "textually represents" this object, such as "s" for the seconds physical
     * unit or "$" for the dollar currency. The result should be a concise but
     * informative representation that is easy for a person to read.
     * </p>
     * 
     * @return a string representation of the unit.
     */
    String getSymbol();

    /**
     * Indicates if this unit is compatible with the unit specified (see
     * {@linkplain Dimension} for a definition of compatible units). Units don't
     * need to be equals to be compatible, for example:
     * 
     * <pre>
     * METRE.equals(YARD) == false
     * METRE.compatibleWith(YARD) == true
     * </pre>
     * 
     * <p>
     * Dimensionless units are never considered compatible unless they are the
     * same unit.
     * </p>
     * 
     * @param unit the other unit to compare with.
     * @return {@code true} if both units are compatible, {@code false}
     *         otherwise.
     * @see Dimension
     */
    boolean compatibleWith(Unit unit);

}